import { AnyAction, Reducer } from 'redux';

import { EffectsCommandMap } from 'dva';
import { Product } from '@/models/product';
import { ProductAttribute } from '../../../models/productAttribute';
import { create } from '@/services/product';
import { removeEmptyProperty } from '../../../utils/utils';

export interface StateType {
  current?: string;
  formData?: Product & ProductAttribute;
}

export type Effect = (
  action: AnyAction,
  effects: EffectsCommandMap & { select: <T>(func: (state: StateType) => T) => T },
) => void;

export interface ModelType {
  namespace: string;
  state: StateType;
  effects: {
    submitStepForm: Effect;
  };
  reducers: {
    saveStepFormData: Reducer<StateType>;
    saveCurrentStep: Reducer<StateType>;
  };
}

const Model: ModelType = {
  namespace: 'addProduct',

  state: {
    current: 'info',
    formData: {
      price: 0,
      originalPrice: 0,
      stock: 0,
      weight: 0,
      previewStatus: 0,
      newStatus: 0,
      recommendStatus: 0,
      serviceIds: [],
    },
  },

  effects: {
    *submitStepForm({ payload, callback }, { call, put }) {
      removeEmptyProperty(payload);
      payload.brandId = payload.brandOption.key;
      payload.brandName = payload.brandOption.label;
      payload.productCategoryId = payload.productCategoryIds[payload.productCategoryIds.length - 1];
      payload.serviceIds = (payload.serviceIds || []).join(',') || '';
      payload.pics = payload.pics || [];
      const data = {};
      const attributeValues: any[] = [];
      Object.keys(payload).forEach(key => {
        if (key.startsWith('#')) {
          attributeValues.push({
            productAttributeId: Number(key.substr(1)),
            value: payload[key],
          });
        } else {
          data[key] = payload[key];
        }
      });
      const formData = new FormData();
      Object.keys(data).forEach(key => {
        if (!(data[key] instanceof Array)) {
          formData.append(key, data[key]);
        }
      });
      payload.albumPics.forEach((file: any) => {
        formData.append('fileList', file.originFileObj, file.originFileObj.name);
      });
      formData.append('attributeValues', JSON.stringify(attributeValues));
      yield call(create, formData);
      callback();
    },
  },

  reducers: {
    saveCurrentStep(state, { payload }) {
      return {
        ...state,
        current: payload,
      };
    },

    saveStepFormData(state, { payload }) {
      return {
        ...state,
        formData: {
          ...(state as StateType).formData,
          ...payload,
        },
      };
    },
  },
};

export default Model;
